import { ITERATE_KEY, TrackOpTypes } from '../utils/index.js';

import { activeEffect, targetMap } from './effect.js';

let withTrack = true; // 开关: 是否开启收集依赖

export const startTrack = () => {
  withTrack = true;
};

export const stopTrack = () => {
  withTrack = false;
};

/**
 * 收集依赖的函数
 * @param {*} target 目标对象
 * @param {TrackOpTypes} type 收集类型
 * @param {*} key 属性名
 */
export default function track(target, type, key) {
  if (!withTrack || !activeEffect) {
    return;
  }

  // 层层查找
  let propMap = targetMap.get(target); // 先根据目标对象，查找其属性的依赖关系
  if (!propMap) {
    propMap = new Map();
    targetMap.set(target, propMap);
  }

  // 如果是遍历所有的属性, key 会等于 undefined
  // 需要堆key做归一化
  if (type === TrackOpTypes.ITERATE) {
    key = ITERATE_KEY;
  }

  // 从属性propMap 查找 拦截类型依赖map
  let typeMap = propMap.get(key);
  if (!typeMap) {
    typeMap = new Map();
    propMap.set(key, typeMap);
  }

  // 从 拦截类型依赖map 查找 依赖函数集合的 depSet
  let depSet = typeMap.get(type);
  if (!depSet) {
    depSet = new Set();
    typeMap.set(type, depSet);
  }
  // 处理 副作用函数
  if (!depSet.has(activeEffect)) {
    depSet.add(activeEffect);
    activeEffect.deps.push(depSet); // 副作用函数动态添加deps属性存储 依赖的 depSet，用于在触发依赖时，删除该副作用函数
  }
}
